#include "reportdialog.h"
#include "ui_reportdialog.h"
#include "mainshare.h"
#include "srsettingsdialog.h"
#include "../smtp/emailsender.h"
#include "../mainframe/mailsettingsdialog.h"

#include <QPainter>
#include <QPrinter>
#include <QPrintDialog>
#include <QPrintPreviewDialog>
#include <QSettings>
#include <QFileDialog>
#include <QEventLoop>
#include <QThread>

ReportDialog::ReportDialog(const StudyRecord &rec, QWidget *parent) :
    m_rec(rec),
    QDialog(parent),
    ui(new Ui::ReportDialog)
{
    ui->setupUi(this);

    ui->nameEdit->setText(rec.patientName);
    ui->sexEdit->setText(sex2trSex(rec.patientSex));
    ui->ageEdit->setText(rec.patientAge);
    ui->studyDateEdit->setText(rec.studyTime.date().toString(SQLITE_DATE_FORMAT));
    ui->accNumEdit->setText(rec.accNumber);
    ui->bodyPartEdit->setText(rec.bodyPart);
    ui->modalityEdit->setText(rec.modality);

    connect(this, SIGNAL(reportProgress(int)), this, SLOT(on_reportProgress(int)));
}

ReportDialog::~ReportDialog()
{
    delete ui;
}

void ReportDialog::on_exportButton_clicked()
{
    QSettings s;
    QString report = s.value(SAVE_FILEPATH, ".").toString();
    if (!m_rec.patientName.isEmpty()) {
        report = report.left(report.lastIndexOf("/")+1);
        report += m_rec.patientName;
        report += m_rec.studyTime.isValid()?(" - "+ m_rec.studyTime.toString(DATETIME_DICOM_FORMAT)):"";
        report += ".pdf";
    }
    report = QFileDialog::getSaveFileName(this, tr("Save Eagle Report"), report, "PDF (*.pdf)");
    if (!report.isEmpty()) {
        ui->exportButton->setDisabled(true);
        s.setValue(SAVE_FILEPATH, report);
        QPrinter printer(QPrinter::HighResolution);
        printer.setOutputFormat(QPrinter::PdfFormat);
        printer.setOutputFileName(report);
        doPrint(&printer);

        if (!ui->emailEdit->text().isEmpty()) {
            EmailSender *s = new EmailSender(ui->emailEdit->text().split(";"), QStringList()<<report);
            QThread *t = new QThread;
            s->moveToThread(t);
            connect(this, SIGNAL(sendMail()), s, SLOT(sendMail()));
            connect(s, SIGNAL(finished(bool,QString)), this, SLOT(on_mailFinished(bool,QString)));
            connect(s, SIGNAL(progress(int)), this, SLOT(on_mailProgress(int)));
            connect(s, SIGNAL(finished(bool,QString)), t, SLOT(quit()));
            connect(t, SIGNAL(finished()), s, SLOT(deleteLater()));
            connect(t, SIGNAL(finished()), t, SLOT(deleteLater()));
            t->start();
            emit sendMail();
        }
    }
}

void ReportDialog::on_mailFinished(bool ok, const QString &msg)
{
    ui->statusLabel->setText(msg);
    ui->exportButton->setEnabled(true);
}

void ReportDialog::on_mailProgress(int value)
{
    ui->statusLabel->setText(tr("Sending report... (%1%)").arg(value));
}

void ReportDialog::on_reportProgress(int value)
{
    ui->statusLabel->setText((value==100)?tr("Report generated successfully"):tr("Generating report... (%1%)").arg(value));
    repaint();
}

void ReportDialog::on_previewButton_clicked()
{
    QPrintPreviewDialog dialog(this);
    connect(&dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(doPrint(QPrinter*)));
    dialog.setWindowFlags(dialog.windowFlags()|Qt::WindowMaximizeButtonHint);
    dialog.exec();
}

void ReportDialog::on_printButton_clicked()
{
    QPrinter printer(QPrinter::HighResolution);
    QPrintDialog dialog(&printer, this);
    if (dialog.exec() == QDialog::Accepted)
        doPrint(&printer);
}

void ReportDialog::doPrint(QPrinter *printer)
{
    emit reportProgress(0);

    QSettings s;
    double left, top, right, bottom;
    left = s.value(PAGE_MARGIN_LEFT, LEFT_MARGIN_DEFAULT).toDouble();
    top = s.value(PAGE_MARGIN_TOP, TOP_MARGIN_DEFAULT).toDouble();
    right = s.value(PAGE_MARGIN_RIGHT, RIGHT_MARGIN_DEFAULT).toDouble();
    bottom = s.value(PAGE_MARGIN_BOTTOM, BOTTOM_MARGIN_DEFALT).toDouble();
    printer->setPageMargins(left, top, right, bottom, QPrinter::Millimeter);

    QPainter painter(printer);
    double mm2dot = printer->resolution()/(double)25.40;

    QRect viewRect = painter.viewport();
    int totalHeight = 0;

    emit reportProgress(5);

    QImage image(":/report/jf-header.png");
    image = image.scaledToWidth(viewRect.width(), Qt::SmoothTransformation);
    painter.drawImage(0, totalHeight, image);
    totalHeight += image.height();

    emit reportProgress(10);

    QFont font = painter.font();
    if (font.fromString(s.value(INSTITUTION_NAME_FONT).toString()))
        painter.setFont(font);
    totalHeight += painter.fontMetrics().lineSpacing();
    QString text = s.value(INSTITUTION_NAME_TEXT).toString();
    int width = painter.fontMetrics().width(text);
    painter.drawText((viewRect.width()-width)/2, totalHeight, text);
    totalHeight += painter.fontMetrics().lineSpacing();

    if (font.fromString(s.value(REPORT_TITLE_FONT).toString()))
        painter.setFont(font);
    totalHeight += painter.fontMetrics().lineSpacing();
    text = s.value(REPORT_TITLE_TEXT).toString();
    width = painter.fontMetrics().width(text);
    painter.drawText((viewRect.width()-width)/2, totalHeight, text);
    totalHeight += painter.fontMetrics().lineSpacing();

    painter.drawLine(0, totalHeight, viewRect.width(), totalHeight);

    emit reportProgress(15);

    if (font.fromString(s.value(PATIENT_INFO_FONT).toString()))
        painter.setFont(font);
    totalHeight += painter.fontMetrics().lineSpacing()*0.5;
    totalHeight += painter.fontMetrics().height();
    painter.drawText(0, totalHeight, tr("Patient Name: ") + m_rec.patientName);
    painter.drawText(viewRect.width()/3, totalHeight, tr("Patient Sex: ") + sex2trSex(m_rec.patientSex));
    painter.drawText(viewRect.width()*2/3, totalHeight, tr("Patient Age: ") + m_rec.patientAge);
    totalHeight += painter.fontMetrics().lineSpacing()*1.5;
    painter.drawText(0, totalHeight, tr("Body Part: ") + m_rec.bodyPart);
    painter.drawText(viewRect.width()/3, totalHeight, tr("Modality: ") + m_rec.modality);
    painter.drawText(viewRect.width()*2/3, totalHeight, tr("Study Date: ") + m_rec.studyTime.date().toString(SQLITE_DATE_FORMAT));
    text = tr("Series Desc: ") + m_rec.seriesDesc + tr("    ") + tr("Study Desc: ") + m_rec.studyDesc;
    width = painter.fontMetrics().width(text);
    if (width > viewRect.width()) {
        totalHeight += painter.fontMetrics().lineSpacing()*1.5;
        if (!m_rec.seriesDesc.isEmpty())
            painter.drawText(0, totalHeight, tr("Series Desc: ") + m_rec.seriesDesc);

        if (!m_rec.studyDesc.isEmpty())
            painter.drawText(0, totalHeight, tr("Study Desc: ") + m_rec.studyDesc);
    } else {
        if ((!m_rec.seriesDesc.isEmpty()) && (!m_rec.studyDesc.isEmpty())) {
            totalHeight += painter.fontMetrics().lineSpacing()*1.5;
            painter.drawText(0, totalHeight, text);
        } else {
            if (!m_rec.seriesDesc.isEmpty()) {
                totalHeight += painter.fontMetrics().lineSpacing()*1.5;
                painter.drawText(0, totalHeight, tr("Series Desc: ") + m_rec.seriesDesc);
            }
            if (!m_rec.studyDesc.isEmpty()) {
                totalHeight += painter.fontMetrics().lineSpacing()*1.5;
                painter.drawText(0, totalHeight, tr("Study Desc: ") + m_rec.studyDesc);
            }
        }
    }
    totalHeight += painter.fontMetrics().lineSpacing()*0.8;

    painter.drawLine(0, totalHeight, viewRect.width(), totalHeight);
    totalHeight += painter.fontMetrics().lineSpacing();

    emit reportProgress(20);

    int imgWidth = s.value(IMAGE_WIDTH, 150.0).toDouble()*mm2dot;
    int imgHeight = s.value(IMAGE_HEIGHT, 150.0).toDouble()*mm2dot;
    if (font.fromString(s.value(REPORT_BODY_FONT).toString()))
        painter.setFont(font);
    if (imgWidth * m_axial.height() > imgHeight * m_axial.width()) {
        image = m_axial.scaledToHeight(imgHeight, Qt::SmoothTransformation);
    } else {
        image = m_axial.scaledToWidth(imgWidth, Qt::SmoothTransformation);
    }

    if (viewRect.height() - totalHeight < image.height() + painter.fontMetrics().lineSpacing()*2) {
        printer->newPage();
        totalHeight = 0;
    }
    totalHeight += painter.fontMetrics().height();
    painter.drawText(0, totalHeight, tr("1. Segmented Image (Axial): "));
    totalHeight += painter.fontMetrics().leading();
    totalHeight += painter.fontMetrics().lineSpacing();
    painter.drawImage((viewRect.width()-image.width())/2, totalHeight, image);
    totalHeight += image.height();
    totalHeight += painter.fontMetrics().lineSpacing();

    emit reportProgress(40);

    if (imgWidth * m_coronal.height() > imgHeight * m_coronal.width()) {
        image = m_coronal.scaledToHeight(imgHeight, Qt::SmoothTransformation);
    } else {
        image = m_coronal.scaledToWidth(imgWidth, Qt::SmoothTransformation);
    }

    if (viewRect.height() - totalHeight < image.height() + painter.fontMetrics().lineSpacing()*2) {
        printer->newPage();
        totalHeight = 0;
    }
    totalHeight += painter.fontMetrics().height();
    painter.drawText(0, totalHeight, tr("2. Segmented Image (Coronal): "));
    totalHeight += painter.fontMetrics().leading();
    totalHeight += painter.fontMetrics().lineSpacing();
    painter.drawImage((viewRect.width()-image.width())/2, totalHeight, image);
    totalHeight += image.height();
    totalHeight += painter.fontMetrics().lineSpacing();

    emit reportProgress(60);

    if (imgWidth * m_sagittal.height() > imgHeight * m_sagittal.width()) {
        image = m_sagittal.scaledToHeight(imgHeight, Qt::SmoothTransformation);
    } else {
        image = m_sagittal.scaledToWidth(imgWidth, Qt::SmoothTransformation);
    }

    if (viewRect.height() - totalHeight < image.height() + painter.fontMetrics().lineSpacing()*2) {
        printer->newPage();
        totalHeight = 0;
    }
    totalHeight += painter.fontMetrics().height();
    painter.drawText(0, totalHeight, tr("3. Segmented Image (Sagittal): "));
    totalHeight += painter.fontMetrics().leading();
    totalHeight += painter.fontMetrics().lineSpacing();
    painter.drawImage((viewRect.width()-image.width())/2, totalHeight, image);
    totalHeight += image.height();
    totalHeight += painter.fontMetrics().lineSpacing();

    emit reportProgress(80);

    image = QImage(":/report/jf-code.png");
    image = image.scaledToWidth(mm2dot*20, Qt::SmoothTransformation);
    if (viewRect.height() - totalHeight < painter.fontMetrics().lineSpacing()*11.5 + image.height()) {
        printer->newPage();
        totalHeight = 0;
    }
    totalHeight += painter.fontMetrics().lineSpacing();
    painter.drawText(0, totalHeight, tr("4. Computer-aided Tumor Assessment: "));
    totalHeight += painter.fontMetrics().lineSpacing();

    totalHeight += painter.fontMetrics().lineSpacing();
    painter.drawText(0, totalHeight, tr("4.1 Tumor Catagory: "));
    totalHeight += painter.fontMetrics().lineSpacing()*1.5;
    painter.drawText(0, totalHeight, tr("    ")+(m_svmScore<0?tr("Malignant"):tr("Benign")));
    totalHeight += painter.fontMetrics().lineSpacing();


    if (font.fromString(s.value(REPORT_TAIL_FONT).toString()))
        painter.setFont(font);
    totalHeight = viewRect.height() - painter.fontMetrics().lineSpacing()*5 - image.height();
    totalHeight += painter.fontMetrics().lineSpacing();
    painter.drawText(0, totalHeight, tr("Request Institution: ") + m_rec.institution);
    totalHeight += painter.fontMetrics().lineSpacing()*1.5;
    painter.drawText(0, totalHeight, tr("Report Time: ") + QDateTime::currentDateTime().toString(SQLITE_DATETIME_FORMAT));
    if (font.fromString(s.value(FOOTNOTE_FONT).toString()))
        painter.setFont(font);
    totalHeight += painter.fontMetrics().lineSpacing()*1.5;
    painter.drawText(0, totalHeight, s.value(FOOTNOTE_TEXT).toString());
    totalHeight += painter.fontMetrics().lineSpacing()*0.6;

    painter.drawLine(0, totalHeight, viewRect.width(), totalHeight);
    totalHeight += painter.fontMetrics().lineSpacing()*0.4;
    QString jf = tr("JF Healthcare WeChat Public");
    text = tr("More Information >>>");
    width = painter.fontMetrics().width(jf);
    width = width>painter.fontMetrics().width(text)?width:painter.fontMetrics().width(text);
    int height = painter.fontMetrics().lineSpacing()*2;
    height = height>image.height()?height:image.height();
    painter.drawText(QRect((viewRect.width()-width-image.width()-int(mm2dot)*4)/2, totalHeight, width, height),
                     Qt::AlignCenter, text + "\n" + jf);
    painter.drawImage((viewRect.width()+width-image.width())/2+int(mm2dot)*4, totalHeight, image);

    emit reportProgress(100);
}
